//
//  UIViewController+OAExtension.m
//  OARetail
//
//  Created by ChenJie on 5/17/20.
//  Copyright © 2020 Mist. All rights reserved.
//

#import "UIViewController+OAExtension.h"
#import <objc/runtime.h>
#import "UIView+OAExtension.h"
#import "OABase.h"

@interface UIViewController ()

@property (nonatomic, assign, setter=oa_setLastContentOffsetY:) CGFloat oa_lastContentOffsetY;
@property (nonatomic, strong, setter=oa_setEndEditingTapGestureRecognizer:) UITapGestureRecognizer *oa_endEditingTapGestureRecognizer;

@end

@implementation UIViewController (OAExtension)

#pragma mark - Public property

/*
 * oa_isHideNavigationBar
 */
- (BOOL)oa_isHideNavigationBar{
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)oa_setIsHideNavigationBar:(BOOL)oa_isHideNavigationBar {
    objc_setAssociatedObject(self, @selector(oa_isHideNavigationBar), @(oa_isHideNavigationBar), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

/*
 * oa_isAvoidKeyboard
 */
- (BOOL)oa_isAvoidKeyboard{
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)oa_setIsAvoidKeyboard:(BOOL)oa_isAvoidKeyboard {
    objc_setAssociatedObject(self, @selector(oa_isAvoidKeyboard), @(oa_isAvoidKeyboard), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

/*
 * oa_isTapViewEndEditing
 */
- (BOOL)oa_isTapViewEndEditing {
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)oa_setIsTapViewEndEditing:(BOOL)oa_isTapViewEndEditing {
    objc_setAssociatedObject(self, @selector(oa_isTapViewEndEditing), @(oa_isTapViewEndEditing), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    if (oa_isTapViewEndEditing) {
        [self.view addGestureRecognizer:self.oa_endEditingTapGestureRecognizer];
    } else {
        [self.view removeGestureRecognizer:self.oa_endEditingTapGestureRecognizer];
    }
}

#pragma mark - Private property

/*
 * oa_lastContentOffsetY
 */
- (CGFloat)oa_lastContentOffsetY {
    return [objc_getAssociatedObject(self, _cmd) floatValue];
}

- (void)oa_setLastContentOffsetY:(CGFloat)oa_lastContentOffsetY {
    objc_setAssociatedObject(self, @selector(oa_lastContentOffsetY), @(oa_lastContentOffsetY), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

/*
 * oa_endEditingTapGestureRecognizer
 */
- (UITapGestureRecognizer *)oa_endEditingTapGestureRecognizer {
    UITapGestureRecognizer *tap = objc_getAssociatedObject(self, _cmd);
    if (!tap) {
        tap = [self oa_createEndEditingTapGestureRecognizer];
        self.oa_endEditingTapGestureRecognizer = tap;
    }
    return tap;
}

- (void)oa_setEndEditingTapGestureRecognizer:(UITapGestureRecognizer *)oa_endEditingTapGestureRecognizer {
    objc_setAssociatedObject(self,
                             @selector(oa_endEditingTapGestureRecognizer),
                             oa_endEditingTapGestureRecognizer,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - Lifecycle methods

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        // viewDidLoad
//        [self SwizzleMethodWithClass:UIViewController.class
//                    originalSelector:@selector(viewDidLoad)
//                    swizzledSelector:@selector(oa_viewDidLoad)];
        
        // viewWillAppear
        [self SwizzleMethodWithClass:UIViewController.class
                    originalSelector:@selector(viewWillAppear:)
                    swizzledSelector:@selector(oa_viewWillAppear:)];
        
        // viewWillDisappear
        [self SwizzleMethodWithClass:UIViewController.class
                    originalSelector:@selector(viewWillDisappear:)
                    swizzledSelector:@selector(oa_viewWillDisappear:)];
        
    });
}

- (void)oa_tapViewEndEditing {
    [self.view addGestureRecognizer:[self oa_endEditingTapGestureRecognizer]];
}

#pragma mark - Private methods

+ (void)SwizzleMethodWithClass:(Class)class
              originalSelector:(SEL)originalSelector
              swizzledSelector:(SEL)swizzledSelector {
    Method originalMethod = class_getInstanceMethod(class, (originalSelector));
    Method swizzledMethod = class_getInstanceMethod(class, (swizzledSelector));
    if (!class_addMethod((class),
                         (originalSelector),
                         method_getImplementation(swizzledMethod),
                         method_getTypeEncoding(swizzledMethod))) {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    } else {
        class_replaceMethod((class),
                            (swizzledSelector),
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    }
}


//- (void)oa_viewDidLoad {
//    [self oa_viewDidLoad];
//
//    if (self.oa_isTapViewEndEditing) {
//        [self.view addGestureRecognizer:[self oa_endEditingTapGestureRecognizer]];
//    }
//}

- (void)oa_viewWillAppear:(BOOL)animated {
    [self oa_viewWillAppear:animated];
    
    if (self.oa_isHideNavigationBar) {
        self.navigationController.navigationBarHidden = YES;
    }
    
    if (self.oa_isAvoidKeyboard) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(oa_keyboardFrameWillChange:)
                                                     name:UIKeyboardWillChangeFrameNotification
                                                   object:nil];
    }
    
}

- (void)oa_viewWillDisappear:(BOOL)animated {
    [self oa_viewWillDisappear:animated];
    
    if (self.oa_isHideNavigationBar) {
        self.navigationController.navigationBarHidden = NO;
    }
    
    if (self.oa_isAvoidKeyboard) {
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:UIKeyboardWillChangeFrameNotification
                                                      object:nil];
    }
    
}

- (UITapGestureRecognizer *)oa_createEndEditingTapGestureRecognizer {
    UITapGestureRecognizer *tap =
    [[UITapGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(oa_endEditingTapGestureRecognizerHandler:)];
    tap.numberOfTapsRequired = 1;
    tap.cancelsTouchesInView = NO;
    
    return tap;
}

#pragma mark - Event response methods

- (void)oa_keyboardFrameWillChange:(NSNotification *)notification {
    
    NSDictionary *userInfo = notification.userInfo;
    CGRect keyboardBeginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
    if (keyboardBeginFrame.origin.y == keyboardEndFrame.origin.y) {
        return;
    }
    
    CGFloat keyboardMargin = 10;
    
    BOOL keyboardWillOpen = keyboardEndFrame.origin.y < keyboardBeginFrame.origin.y;
    
    UIView *activeView = [self.view oa_firstResponder];
    CGRect activeViewFrame = [activeView.superview convertRect:activeView.frame toView:nil];
    CGFloat activeViewBottom = MIN(CGRectGetMaxY(activeViewFrame), [UIScreen mainScreen].bounds.size.height);
    CGFloat offsetY = activeViewBottom + keyboardMargin - keyboardEndFrame.origin.y;
    UIScrollView *scrollViewContainer = [activeView oa_scrollViewContainer];
    
    if (keyboardWillOpen) { // 键盘打开
        if (offsetY > 0) {
            if (scrollViewContainer) {
                scrollViewContainer.oa_contentOffsetY += offsetY;
            } else {
                
            }
            
            self.oa_lastContentOffsetY = offsetY;
        }
    } else {
        if (self.oa_lastContentOffsetY > 0) {
            if (scrollViewContainer) {
                scrollViewContainer.oa_contentOffsetY -= self.oa_lastContentOffsetY;
            } else {
                
            }
            
            self.oa_lastContentOffsetY = 0;
        }
    }
}

- (void)oa_endEditingTapGestureRecognizerHandler:(UITapGestureRecognizer *)tap {
    [self.view endEditing:YES];
}

@end
